package com.nutrition.health.service.impl;

import com.nutrition.health.model.FoodItem;
import com.nutrition.health.model.FoodItem.FoodCategory;
import com.nutrition.health.model.NutritionInfo;
import com.nutrition.health.repository.FoodItemRepository;
import com.nutrition.health.repository.NutritionInfoRepository;
import com.nutrition.health.service.KimiAIService;
import com.nutrition.health.service.FoodItemService;
import com.nutrition.health.util.JsonUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.transaction.Transactional;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Random;

@Service
@Transactional
public class FoodItemServiceImpl implements FoodItemService {

    private static final Logger logger = LoggerFactory.getLogger(FoodItemServiceImpl.class);

    private final FoodItemRepository foodItemRepository;
    private final NutritionInfoRepository nutritionInfoRepository;
    private final KimiAIService kimiAIService;

    @Autowired
    public FoodItemServiceImpl(FoodItemRepository foodItemRepository,
                               NutritionInfoRepository nutritionInfoRepository,
                               KimiAIService kimiAIService) {
        this.foodItemRepository = foodItemRepository;
        this.nutritionInfoRepository = nutritionInfoRepository;
        this.kimiAIService = kimiAIService;
    }

    @Override
    public List<FoodItem> getAllFoodItems() {
        return foodItemRepository.findAll();
    }

    @Override
    public Page<FoodItem> getAllFoodItems(Pageable pageable) {
        return foodItemRepository.findAll(pageable);
    }

    @Override
    public Optional<FoodItem> getFoodItemById(Long id) {
        return foodItemRepository.findById(id);
    }

    @Override
    public Optional<FoodItem> getFoodItemByBarcode(String barcode) {
        return foodItemRepository.findByBarcode(barcode);
    }

    @Override
    public List<FoodItem> getFoodItemsByCategory(FoodCategory category) {
        return foodItemRepository.findByCategory(category);
    }

    @Override
    public Page<FoodItem> searchFoodItems(String keyword, Pageable pageable) {
        return foodItemRepository.searchByKeyword(keyword, pageable);
    }

    @Override
    public FoodItem createFoodItem(FoodItem foodItem) {
        return foodItemRepository.save(foodItem);
    }

    @Override
    public FoodItem updateFoodItem(Long id, FoodItem foodItemDetails) {
        FoodItem foodItem = foodItemRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("Food item not found with id: " + id));

        foodItem.setName(foodItemDetails.getName());
        foodItem.setDescription(foodItemDetails.getDescription());
        foodItem.setCategory(foodItemDetails.getCategory());
        foodItem.setImageUrl(foodItemDetails.getImageUrl());
        foodItem.setBarcode(foodItemDetails.getBarcode());

        return foodItemRepository.save(foodItem);
    }

    @Override
    public void deleteFoodItem(Long id) {
        foodItemRepository.deleteById(id);
    }

    @Override
    public NutritionInfo getNutritionInfo(Long foodItemId) {
        return nutritionInfoRepository.findByFoodItemId(foodItemId)
                .orElseThrow(() -> new RuntimeException("Nutrition info not found for food item id: " + foodItemId));
    }

    @Override
    public NutritionInfo updateNutritionInfo(Long foodItemId, NutritionInfo nutritionInfoDetails) {
        FoodItem foodItem = foodItemRepository.findById(foodItemId)
                .orElseThrow(() -> new RuntimeException("Food item not found with id: " + foodItemId));

        NutritionInfo nutritionInfo = nutritionInfoRepository.findByFoodItem(foodItem)
                .orElseGet(() -> {
                    NutritionInfo newInfo = new NutritionInfo();
                    newInfo.setFoodItem(foodItem);
                    return newInfo;
                });

        nutritionInfo.setCalories(nutritionInfoDetails.getCalories());
        nutritionInfo.setServingSize(nutritionInfoDetails.getServingSize());
        nutritionInfo.setProtein(nutritionInfoDetails.getProtein());
        nutritionInfo.setCarbohydrates(nutritionInfoDetails.getCarbohydrates());
        nutritionInfo.setFat(nutritionInfoDetails.getFat());
        nutritionInfo.setSaturatedFat(nutritionInfoDetails.getSaturatedFat());
        nutritionInfo.setTransFat(nutritionInfoDetails.getTransFat());
        nutritionInfo.setCholesterol(nutritionInfoDetails.getCholesterol());
        nutritionInfo.setSodium(nutritionInfoDetails.getSodium());
        nutritionInfo.setPotassium(nutritionInfoDetails.getPotassium());
        nutritionInfo.setFiber(nutritionInfoDetails.getFiber());
        nutritionInfo.setSugar(nutritionInfoDetails.getSugar());
        nutritionInfo.setVitaminA(nutritionInfoDetails.getVitaminA());
        nutritionInfo.setVitaminC(nutritionInfoDetails.getVitaminC());
        nutritionInfo.setCalcium(nutritionInfoDetails.getCalcium());
        nutritionInfo.setIron(nutritionInfoDetails.getIron());
        nutritionInfo.setAdditionalNutrients(nutritionInfoDetails.getAdditionalNutrients());

        return nutritionInfoRepository.save(nutritionInfo);
    }

    @Override
    public FoodItem analyzeFoodImage(MultipartFile image) {
        try {
            logger.info("Analyzing food image: {}", image.getOriginalFilename());
            
            // 调用 Kimi AI 服务分析图片
            Map<String, Object> analysisResult = kimiAIService.analyzeFoodImage(image);
            
            // 创建食品项
            FoodItem foodItem = new FoodItem();
            
            // 设置食品名称和描述
            String name = (String) analysisResult.getOrDefault("name", "未识别食品");
            foodItem.setName(name);
            foodItem.setDescription("通过AI分析识别的" + name);
            
            // 设置食品类别
            String category = (String) analysisResult.getOrDefault("category", "其他");
            FoodCategory foodCategory = mapToFoodCategory(category);
            foodItem.setCategory(foodCategory);
            
            // 创建营养信息
            NutritionInfo nutritionInfo = new NutritionInfo();
            nutritionInfo.setFoodItem(foodItem);
            
            // 设置基本营养成分
            nutritionInfo.setServingSize(100.0); // 默认每100克
            nutritionInfo.setCalories((Double) analysisResult.getOrDefault("calories", 0.0));
            nutritionInfo.setProtein((Double) analysisResult.getOrDefault("protein", 0.0));
            nutritionInfo.setFat((Double) analysisResult.getOrDefault("fat", 0.0));
            nutritionInfo.setCarbohydrates((Double) analysisResult.getOrDefault("carbs", 0.0));
            nutritionInfo.setFiber((Double) analysisResult.getOrDefault("fiber", 0.0));
            
            // 设置维生素和矿物质
            @SuppressWarnings("unchecked")
            Map<String, String> vitamins = (Map<String, String>) analysisResult.getOrDefault("vitamins", new HashMap<String, String>());
            if (vitamins.containsKey("C")) {
                try {
                    String vitaminC = vitamins.get("C").replaceAll("[^0-9.]", "");
                    nutritionInfo.setVitaminC(Double.parseDouble(vitaminC));
                } catch (NumberFormatException e) {
                    logger.warn("Failed to parse vitamin C value: {}", vitamins.get("C"));
                }
            }
            
            @SuppressWarnings("unchecked")
            Map<String, String> minerals = (Map<String, String>) analysisResult.getOrDefault("minerals", new HashMap<String, String>());
            if (minerals.containsKey("钙")) {
                try {
                    String calcium = minerals.get("钙").replaceAll("[^0-9.]", "");
                    nutritionInfo.setCalcium(Double.parseDouble(calcium));
                } catch (NumberFormatException e) {
                    logger.warn("Failed to parse calcium value: {}", minerals.get("钙"));
                }
            }
            
            // 保存完整分析结果
            String fullAnalysis = (String) analysisResult.getOrDefault("fullAnalysis", "");
            // 使用 JsonUtils 将分析结果转换为 JSON 字符串
            Map<String, Object> additionalData = new HashMap<>();
            additionalData.put("aiAnalysis", fullAnalysis);
            String additionalNutrientsJson = JsonUtils.toJson(additionalData);
            nutritionInfo.setAdditionalNutrients(additionalNutrientsJson);
            
            foodItem.setNutritionInfo(nutritionInfo);
            
            return foodItem;
            
        } catch (Exception e) {
            logger.error("Failed to analyze food image", e);
            throw new RuntimeException("Failed to analyze food image: " + e.getMessage(), e);
        }
    }
    
    /**
     * 将文本类别映射到枚举类别
     * @param category 文本类别
     * @return 枚举类别
     */
    private FoodCategory mapToFoodCategory(String category) {
        if (category == null) {
            return FoodCategory.OTHER;
        }
        
        category = category.toLowerCase();
        
        if (category.contains("水果") || category.contains("fruit")) {
            return FoodCategory.FRUITS;
        } else if (category.contains("蔬菜") || category.contains("vegetable")) {
            return FoodCategory.VEGETABLES;
        } else if (category.contains("谷物") || category.contains("grain")) {
            return FoodCategory.GRAINS;
        } else if (category.contains("蛋白质") || category.contains("protein") ||
                  category.contains("肉") || category.contains("meat") ||
                  category.contains("豆") || category.contains("bean")) {
            return FoodCategory.PROTEINS;
        } else if (category.contains("乳制品") || category.contains("dairy")) {
            return FoodCategory.DAIRY;
        } else if (category.contains("零食") || category.contains("snack")) {
            return FoodCategory.SNACKS;
        } else if (category.contains("饮料") || category.contains("beverage")) {
            return FoodCategory.BEVERAGES;
        } else {
            return FoodCategory.OTHER;
        }
    }

    @Override
    public List<FoodItem> findFoodItemsByNutrientConstraints(Double maxCalories, Double minProtein, Double maxCarbs) {
        // 这里简化实现，实际应该使用更复杂的查询
        List<FoodItem> result = new ArrayList<>();
        
        // 获取所有符合卡路里限制的食品
        List<FoodItem> calorieFilteredItems = foodItemRepository.findByMaxCalories(maxCalories);
        
        // 获取所有符合蛋白质要求的食品
        List<FoodItem> proteinFilteredItems = foodItemRepository.findByMinProtein(minProtein);
        
        // 取交集
        for (FoodItem item : calorieFilteredItems) {
            if (proteinFilteredItems.contains(item)) {
                // 检查碳水化合物限制
                NutritionInfo info = item.getNutritionInfo();
                if (info != null && info.getCarbohydrates() <= maxCarbs) {
                    result.add(item);
                }
            }
        }
        
        return result;
    }
}